package com.liang.ali.yoloxgrpc1;

import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.output.BoundingBox;
import ai.djl.modality.cv.output.DetectedObjects;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;

import static java.lang.Math.*;

/*
 * @Author iLy
 * @Description
 * @ClassName PainImage
 * @Date 2021/11/4 14:06
 * @VERSION 1.0
 **/
public class PainImage {
    static List<String> CLASSES = Arrays.asList("can", "bottle", "branch", "hay", "small-white", "grass",
            "leaf", "plastic-bag", "cup", "ship", "person", "the-nets", "water-float", "flower",
            "lotus-leaf", "paper", "black-floaters", "milk-box", "bubble", "bigunknow", "float1",
            "float2", "distance", "ball");

    public static void painImageAuthority(String file, Integer[] classes, Float[] scores, float[][] boxes) throws IOException {
        Image imgArr = ImageFactory.getInstance().fromFile(Paths.get(file));
        imgArr.getWrappedImage();

        List<String> classNames = new ArrayList();
        for (int i = 0; i < scores.length; i++) {
            classNames.add(CLASSES.get(classes[i]));
        }

        List<Double> prob = new ArrayList<>();
        for (int i = 0; i < scores.length; i++) {
            prob.add((double) scores[i]);
        }

        List<BoundingBox> boxes1 = new ArrayList<>();
        for (int i = 0; i < boxes.length; i++) {
            boxes1.add(bboxToRectangle(boxes[i], imgArr.getWidth(), imgArr.getHeight()));
        }


        DetectedObjects detectedObjects = new DetectedObjects(classNames, prob, boxes1);

        imgArr.drawBoundingBoxes(detectedObjects);
        imgArr.getWrappedImage();

        LocalDateTime localDateTime = LocalDateTime.now();
        String name =  localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss"));

        FileOutputStream out = new FileOutputStream("D:\\image\\"+ name+".jpg");
        imgArr.save(out,"jpg");

    }

    public static ai.djl.modality.cv.output.Rectangle bboxToRectangle(float[] bbox, int width, int height){
        // Convert the coordinates into the
        // bounding box coordinates format
        return new ai.djl.modality.cv.output.Rectangle(bbox[1]/width, bbox[0]/height, (bbox[3]-bbox[1])/width, (bbox[2]-bbox[0])/height);
    }

    public static void painImage(String file, Integer[] classes, Float[] scores, float[][] boxes, String outputFolder) throws Exception {
        List<Color> preColors = new ArrayList<>();
        for (int i = 0; i < CLASSES.size(); i++) {
            float i1 = i*1.0000f / CLASSES.size();

            Random random = new Random();
            float hue = (random.nextInt(3200) + 6200) / 10000f;
            // sat between 0.1 and 0.3。
            //saturation变量表示颜色的饱和度，取值为0-1之间的浮点值。
            //这里设置为0.1-0.3范围之间。
            float saturation = (random.nextInt(3200) + 6200) / 10000f;
            //luminance变量表示颜色的亮度，取值也是0-1之间的浮点值。
            //这里取值为0.9。
//            float luminance = (random.nextInt(3200) + 6200) / 10000f;
            float luminance = 0.99f;
            //getHSBColor函数创建一个基于hsb颜色模型的color对象。
            //Color color1 = Color.getHSBColor(hue, saturation, luminance);
            Color color1 =  Color.getHSBColor(hue, saturation, luminance);
            preColors.add(color1);
        }

        Collections.shuffle(preColors);

        BufferedImage image = ImageIO.read(new FileInputStream(file));
        int width = image.getWidth();
        int height = image.getHeight();
        Graphics2D g = image.createGraphics();//得到图形上下文，画框
        Graphics2D gLabel = image.createGraphics();//得到图形上下文，写字

        int thickness = Math.max((width + height) / 300, 1);

        System.out.println("width=>"+width);

        Font labelFone = new Font("Century", Font.PLAIN, (int) (3e-2 * height + 0.5));

        g.setFont(new Font("Century", Font.PLAIN, thickness));
        gLabel.setFont(labelFone);//写入签名

        for (int i = 0; i < classes.length; i++) {
            //类别
            String predicted_class = CLASSES.get(classes[i]);
            //框
            float[] box = boxes[i];
            //置信度
            float score = scores[i];
            Integer aClass = classes[i];
            g.setColor(preColors.get(aClass));
            gLabel.setColor(new Color(255,255,255));

            double top,left,bottom,right;
            top = box[0] / 416 * height;
            left = box[1] / 416 * width;
            bottom = box[2] / 416 * height;
            right = box[3] / 416 * width;

            top = top - 5;
            left = left - 5;
            bottom = bottom + 5;
            right = right + 5;

            //目标框的上、左两个坐标小数点后一位四舍五入
            top = max(0, (int)floor(top + 0.5));
            left = max(0, (int)floor(left + 0.5));
            //目标框的下、右两个坐标小数点后一位四舍五入，与图片的尺寸相比，取最小值
            bottom = min(image.getHeight(), (int)floor(bottom + 0.5));
            right = min(image.getWidth(), (int)floor(right + 0.5));

            String label = predicted_class + String.format("%.2f", score);
            FontMetrics fm = gLabel.getFontMetrics(labelFone);
            int[] stringLength = FontUtil.getStringWidthandHeight(label, fm);

            for (int i1 = 0; i1 < thickness; i1++) {
                g.drawRect((int)left+i1, (int)top+i1, (int)(right-left)-2*i1, (int)(bottom-top)-2*i1);
            }
            if (top - stringLength[0] >= 0){
                g.drawRect((int)left , (int)top - stringLength[0] + 5, stringLength[1], stringLength[0]);
                g.fillRect((int)left , (int)top - stringLength[0] + 5, stringLength[1], stringLength[0]);
                gLabel.drawString(label,(float) left,(float)top);
            }
            else {
                g.drawRect((int)left , (int)bottom, stringLength[1], (int) (stringLength[0]));
                g.fillRect((int)left , (int)bottom, stringLength[1], (int) (stringLength[0]));
                gLabel.drawString(label,(float) left,(float)bottom + stringLength[0] - 5);
            }



        }
        g.dispose();

        LocalDateTime localDateTime = LocalDateTime.now();
        String name =  localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss"));

        File isOutputFolder = new File(outputFolder);
        if (!isOutputFolder.exists()){
            isOutputFolder.mkdirs();//创建目录
        }
        FileOutputStream out = new FileOutputStream(outputFolder+"\\"+name+".jpg");
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(image);
        out.close();
    }
}
